{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "37d4d9dd",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch.nn as nn\n",
    "import torch"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f497505d",
   "metadata": {},
   "source": [
    "# CNN"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "271cfcc9",
   "metadata": {},
   "source": [
    "## 卷积"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a0490f48",
   "metadata": {},
   "source": [
    "$ output = \\lfloor \\frac{input+2 \\times padding - kernel_size}{s} \\rfloor +1 $"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "3f4bfc4e",
   "metadata": {},
   "outputs": [],
   "source": [
    "conv = nn.Conv2d(in_channels=3, out_channels=6, kernel_size=(2, 1), bias=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "bffafb54",
   "metadata": {},
   "outputs": [],
   "source": [
    "img = torch.randn(4, 3, 256, 224)         # B, C, H, W"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "51a6a74d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "feat尺寸:torch.Size([4, 6, 255, 224])\n"
     ]
    }
   ],
   "source": [
    "feat = conv(img)\n",
    "print(f'feat尺寸:{feat.shape}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "f72e1741",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([6, 3, 2, 1])\n"
     ]
    }
   ],
   "source": [
    "for param in conv.parameters():\n",
    "    print(param.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc0495e7",
   "metadata": {},
   "source": [
    "## 分组卷积"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "27ceadd8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "feat_group尺寸:torch.Size([4, 6, 255, 224])\n"
     ]
    }
   ],
   "source": [
    "conv_group = nn.Conv2d(in_channels=3, out_channels=6, kernel_size=(2, 1), bias=False, groups=3)\n",
    "feat_group = conv_group(img)\n",
    "print(f'feat_group尺寸:{feat_group.shape}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "35dc3cb7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([6, 1, 2, 1])\n"
     ]
    }
   ],
   "source": [
    "for param in conv_group.parameters():\n",
    "    print(param.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "73e0b2d8",
   "metadata": {},
   "source": [
    "> 实际上，这里的参数是三个卷积核，每个卷积核的输出是两个通道；最终的结果是三个输出结果concat起来"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9bac9ef0",
   "metadata": {},
   "source": [
    "# 线性层"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "d232da71",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "input_linear尺寸:torch.Size([4, 256, 224, 3])\n",
      "out.shape:torch.Size([4, 256, 224, 6])\n",
      "torch.Size([6, 3])\n"
     ]
    }
   ],
   "source": [
    "linear = nn.Linear(in_features=3, out_features=6, bias=False)\n",
    "input_linear = img.permute(0, 2, 3, 1)\n",
    "print(f'input_linear尺寸:{input_linear.shape}')\n",
    "out = linear(input_linear)\n",
    "print(f'out.shape:{out.shape}')\n",
    "for param in linear.parameters():\n",
    "    print(param.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2a81bff0",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
